/**
 * @Author       : Mo 2427995270@qq.com
 * @Date         : 2025-04-30 13:45:54
 * @LastEditTime : 2025-06-05 10:58:35
 * @FilePath     : \KT-02CS-APP\hal_drivers\ll_pwm.c
 * @Description  : pwm低层驱动
 * @Version      : V1.0
 * @History      : 
 * @Note         : 
 */
/***************************************Includes***********************************/
#include "ll_pwm.h"
#include "ll_gpio.h"

#if defined(GD32F407)
#include "gd32f4xx.h"
#elif defined(GD32F10X_HD)
#include "gd32f10x.h"
#elif defined(STM32F10X_HD)
#include "stm32f10x.h"
#elif defined(STM32F40_41xxx)
#include "stm32f4xx.h"
#elif defined(PY32F071xB)
#include "py32f0xx.h"
#else
#error "No device selected"
#endif

/************************************Private Macros********************************/
//#define


/**********************************Private Statement*******************************/


/***********************************Public Variables*******************************/



/**********************************Private Variables*******************************/

static int pwm_ll_calculate_param_reg16(uint32_t clk, uint32_t frequency, uint32_t arr_min, uint32_t *psc, uint32_t *arr);


/**********************************Public Functions********************************/

/**
 * @brief 初始化PWM
 * @param  plt              PWM句柄
 * @param  timer            定时器
 * @param  timer_ch         定时器通道
 * @param  port             端口
 * @param  pinnum           GPIO号
 * @param  frequency        频率
 * @param  polarity         极性 1为高电平有效，0为低电平有效
 * @return int 0成功 -1失败
 * @note null
 */
int pwm_ll_init(pwm_ll_t * plt, uint32_t timer, uint32_t timer_ch, uint32_t port, uint32_t pinnum, uint32_t frequency, int polarity) {
    gpio_ll_t gpio_ll;
    plt->timer = timer;
    plt->timer_ch = timer_ch;
    plt->port = port;
    plt->pinnum = pinnum;
    plt->frequency = frequency;
    uint32_t af_num;
    // clang-format off
#if defined(GD32F407) || defined(GD32F10X_HD)
    #if defined(GD32F407)
        switch (timer) {
        case TIMER0: af_num = GPIO_AF_1; rcu_periph_clock_enable(RCU_TIMER0); break;
        case TIMER1: af_num = GPIO_AF_1; rcu_periph_clock_enable(RCU_TIMER1); break;
        case TIMER2: af_num = GPIO_AF_2; rcu_periph_clock_enable(RCU_TIMER2); break;
        case TIMER3: af_num = GPIO_AF_2; rcu_periph_clock_enable(RCU_TIMER3); break;
        case TIMER4: af_num = GPIO_AF_2; rcu_periph_clock_enable(RCU_TIMER4); break;
        case TIMER7: af_num = GPIO_AF_3; rcu_periph_clock_enable(RCU_TIMER7); break;
        case TIMER8: af_num = GPIO_AF_3; rcu_periph_clock_enable(RCU_TIMER8); break;
        case TIMER11: af_num = GPIO_AF_9; rcu_periph_clock_enable(RCU_TIMER11); break;
        case TIMER5:
        case TIMER6:
        case TIMER9: 
        case TIMER10: 
        case TIMER12: 
        case TIMER13: 
        default: return -1;
        }
        gpio_ll_init(&gpio_ll, port, pinnum, GPIO_LL_MODE_AF, GPIO_LL_OTYPE_PP, GPIO_LL_PULL_NO, GPIO_LL_SPEED_MEDIUM, af_num);
        timer_oc_parameter_struct timer_ocintpara;
        timer_parameter_struct timer_initpara;
        rcu_timer_clock_prescaler_config(RCU_TIMER_PSC_MUL4);
        if (pwm_ll_calculate_param_reg16(SystemCoreClock, frequency, 4000, &plt->psc, &plt->period_cnt) == 0) {
        } else if(pwm_ll_calculate_param_reg16(SystemCoreClock, frequency, 3000, &plt->psc, &plt->period_cnt) == 0) {
        } else if (pwm_ll_calculate_param_reg16(SystemCoreClock, frequency, 2000, &plt->psc, &plt->period_cnt) == 0) {
        } else if (pwm_ll_calculate_param_reg16(SystemCoreClock, frequency, 1000, &plt->psc, &plt->period_cnt) == 0) {
            return -1; // 无法满足要求
        }
        timer_initpara.prescaler = plt->psc;
        timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
        timer_initpara.counterdirection = TIMER_COUNTER_UP;
        timer_initpara.period = plt->period_cnt;
        timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
        timer_initpara.repetitioncounter = 0;
        timer_init(timer, &timer_initpara);
        // pwm通道配置
        timer_ocintpara.ocpolarity = (polarity == 1) ? TIMER_OC_POLARITY_HIGH : TIMER_OC_POLARITY_LOW;
        timer_ocintpara.outputstate = TIMER_CCX_ENABLE;
        timer_ocintpara.ocnpolarity = TIMER_OCN_POLARITY_HIGH;
        timer_ocintpara.outputnstate = TIMER_CCXN_DISABLE;
        timer_ocintpara.ocidlestate = TIMER_OC_IDLE_STATE_LOW;
        timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW;
        timer_channel_output_config(timer, timer_ch, &timer_ocintpara);
        // 设置PWM模式和占空比
        timer_channel_output_pulse_value_config(timer, timer_ch, 0);
        timer_channel_output_mode_config(timer, timer_ch, TIMER_OC_MODE_PWM0);
        timer_channel_output_shadow_config(timer, timer_ch, TIMER_OC_SHADOW_DISABLE);
        // 使能自动重载预装载
        timer_auto_reload_shadow_enable(timer);
        // 使能定时器
        timer_enable(timer);
    #endif
    return 0;
#elif defined(STM32F40_41xxx) || defined(STM32F10X_HD)

        return 0;
#elif defined(PY32F071xB)

#endif

// clang-format on
    return -1; // 未知定时器
}

/**
 * @brief 设置PWM占空比
 * @param  plt              PWM句柄
 * @param  duty_cycle       占空比（0-100.0）
 * @note null
 */
void pwm_ll_set_duty_cycle(pwm_ll_t *plt, float duty_cycle) {
    if (duty_cycle < 0) {
        duty_cycle = 0; // 最小占空比
    } else if (duty_cycle > 100.0f) {
        duty_cycle = 100.0f; // 最大占空比
    }
    uint32_t pulse_value = (uint32_t)(plt->period_cnt * duty_cycle / 100.0f);
#if defined(GD32F407) || defined(GD32F10X_HD)
    // 设置PWM占空比
    timer_channel_output_pulse_value_config(plt->timer, plt->timer_ch, pulse_value);
#elif defined(STM32F40_41xxx) || defined(STM32F10X_HD)
    
#elif defined(PY32F071xB)
    
#endif
}
/**********************************Private Functions*******************************/
/**
 * @brief 计算PWM配置参数（PSC和ARR）16位寄存器版
 * @param clk            定时器时钟频率（Hz）
 * @param frequency      目标PWM频率（Hz）
 * @param psc_out        输出的预分频器值
 * @param arr_out        输出的重载寄存器值
 * @return 0成功，-1失败（频率过低或无法满足ARR最小要求）
 */
static int pwm_ll_calculate_param_reg16(uint32_t clk, uint32_t frequency, uint32_t arr_min, uint32_t *psc, uint32_t *arr) {
    if (frequency == 0 || clk == 0) {
        return -1; // Invalid parameters
    }
    uint32_t total_div = clk / frequency;
    uint32_t best_error = UINT32_MAX;
    uint16_t best_psc = 0;
    uint16_t best_arr = 0;

    // 遍历可能的ARR+1值（从1001到65536或total_div）
    for (uint32_t arr_plus_1 = arr_min; arr_plus_1 <= 65536; arr_plus_1++) {
        if (total_div % arr_plus_1 != 0) {
            continue; // 必须整除
        }
        uint32_t psc_plus_1 = total_div / arr_plus_1;
        if (psc_plus_1 > 65536) {
            continue; // PSC+1超出16位范围
        }
        // 计算实际频率误差
        uint32_t actual_freq = clk / (psc_plus_1 * arr_plus_1);
        uint32_t error = (actual_freq > frequency) ? (actual_freq - frequency) : (frequency - actual_freq);

        // 更新最优解
        if (error < best_error) {
            best_error = error;
            best_psc = (uint16_t)(psc_plus_1 - 1);
            best_arr = (uint16_t)(arr_plus_1 - 1);
        }

        // 提前终止条件：如果误差为0，直接返回
        if (error == 0) {
            break;
        }
    }
    // 检查是否找到有效解
    if (best_error == UINT32_MAX) {
        return -1; // 无解（频率过低或无法满足ARR≥1000）
    }

    *psc = best_psc;
    *arr = best_arr;

    return 0; // Success
}

/* [] END OF FILE */
